package com.groupbuying.settleproducer.controller;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.groupbuying.settleproducer.connector.StoreFeign;
import com.groupbuying.settleproducer.constants.*;
import com.groupbuying.settleproducer.domain.SettleUshopSplitRluesDO;
import com.groupbuying.settleproducer.service.SettleRefundService;
import com.groupbuying.settleproducer.service.impl.SettleUshopSplitMaininfoServiceImpl;
import com.groupbuying.settleproducer.utils.JsonUtils;
import com.groupbuying.settleproducer.utils.apiresult.ApiResult;
import com.groupbuying.settleproducer.utils.apiresult.ApiResultCode;
import org.apache.commons.collections4.MapUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import com.groupbuying.settleproducer.domain.SettleUshopRefundDO;
import com.groupbuying.settleproducer.service.SettleUshopRefundService;
import com.groupbuying.settleproducer.utils.PageUtils;
import com.groupbuying.settleproducer.utils.Query;
import com.groupbuying.settleproducer.utils.R;

/**
 * 分账退款表
 * 
 * @author cuich
 * @email cuichanghao@linku.com.cn
 * @date 2019-06-10 04:10:16
 */
@RestController
@RequestMapping("/settleproducer/settleUshopRefund")
public class SettleUshopRefundController {

	private static final Logger logger = LoggerFactory.getLogger(SettleUshopRefundController.class);

	@Autowired
	private SettleUshopRefundService settleUshopRefundService;

	@Autowired
	private SettleRefundService settleRefundService;

	@Autowired
	private SettleUshopSplitMaininfoServiceImpl settleUshopSplitMaininfoService;

	@Autowired
	private StoreFeign storeFeign;

	/**
	 * @api {post} /settleproducer/settleUshopRefund/RefundSettlement 商户退款接口
	 * @apiExample
	 * author cuich
	 * tar 用于够样团购服务商后台调试
	 * date 2019年10月28日16:17:47
	 * @apiGroup SettleProducer
	 * @apiVersion 1.0.0
	 * @apiParam {String} amount 退款金额
	 * @apiParam {String} orderId 订单号
	 * @apiParam {String} refundPwd 退款密码
	 * @apiSuccess {Integer} code 请求结果 0-失败 1-成功 11-正在分账中,请稍后再试 12-该订单已退款 13-退款密码失败or获取退款密码失败
	 */
	@PostMapping("RefundSettlement")
	@Transactional(rollbackFor = Exception.class)
	public ApiResult RefundSettlement(@RequestBody Map<String, Object> params){
        String orderId = (String) params.get(SettleUshopRefundSearchConstants.SEARCH_ORDERID);
        try{
            //1、校验参数和订单合法性
            ApiResult checkRefundResult = settleRefundService.checkRefund(params);
			logger.error("SettleUshopRefundController-->RefundSettlement "+orderId+" checkRefundResult:"+JsonUtils.objectToJson(checkRefundResult));

            if(!ApiResultCode.SUCCESS.code().equals(checkRefundResult.getCode())){
            	//如果是预分账不成功状态不修改订单状态
            	if(ApiResultCode.PRESPLIT_ERROR.code().equals(checkRefundResult.getCode())|| ApiResultCode.REFUND_GETREFUNDPWD_ERROR.code().equals(checkRefundResult.getCode())){
					return checkRefundResult;
				}
                //修改订单状态为退款失败
                Map<String,Object> orderMsg = new HashMap();
                orderMsg.put("orderId",orderId);
                settleRefundService.sendOrderMessage(orderMsg,OrderUshopEnumConstants.ENUM_ORDERSTATE_REFUNDFAIL);
                return checkRefundResult;
            }
			Map<String,Object> checkRefundMap = (Map<String, Object>) checkRefundResult.getResult();
			String payType = (String) checkRefundMap.get("payType");
			String payId = (String) checkRefundMap.get("payId");
			Map orderInfo = (Map) checkRefundMap.get("orderInfo");
			BigDecimal payInfoAmount = (BigDecimal) checkRefundMap.get("payInfoAmount");
			params.put("orderInfo",orderInfo);
			params.put("payType",payType);
			params.put("payId",payId);
			params.put("payInfoAmount",payInfoAmount);
			Map<String,Object> refundParams = settleRefundService.initRefundParams(orderId);
			if(MapUtils.isEmpty(refundParams)){
                Map<String,Object> orderMsg = new HashMap();
                orderMsg.put("orderId",orderId);
                settleRefundService.sendOrderMessage(orderMsg,OrderUshopEnumConstants.ENUM_ORDERSTATE_REFUNDFAIL);
				return ApiResult.failure(ApiResultCode.FAILURE.code(),"获取参数失败");
			}
			String refundReason = "支付单号:"+refundParams.get("outTradeNo")
					+"，此笔订单的总金额为:"+params.get("amount")+"元";
			params.putAll(refundParams);
			params.put("refundReason",refundReason);
			//冻结退款金额
			params.put("operType",StoreVirtualOperConstants.IN_FREEZE_MONEY);
			ApiResult freezeResult = settleRefundService.freezeOrUnFreezeVirtualMoney(params);
			if(!ApiResultCode.SUCCESS.code().equals(freezeResult.getCode())){
				logger.error("SettleUshopRefundController-->RefundSettlement "+orderId+" freezeOrUnFreezeVirtualMoney fail");
                //修改订单状态为退款失败
                Map<String,Object> orderMsg = new HashMap();
                orderMsg.put("orderId",orderId);
                settleRefundService.sendOrderMessage(orderMsg,OrderUshopEnumConstants.ENUM_ORDERSTATE_REFUNDFAIL);
				return ApiResult.failure("冻结商户资金失败");
			}
			//通知订单中心修改订单状态
			Map<String,Object> orderRefundingMsg = new HashMap();
			orderRefundingMsg.put("orderId",orderId);
			settleRefundService.sendOrderMessage(orderRefundingMsg,OrderUshopEnumConstants.ENUM_ORDERSTATE_REFUNDING);
			//查询商户的相关信息
			ApiResult storeResult = settleRefundService.getStoreInfo(params);
			Map<String,Object> storeMap = (Map<String, Object>) storeResult.getResult();
			if(!ApiResultCode.SUCCESS.code().equals(storeResult.getCode()) || null == storeMap){
				logger.error("SettleUshopRefundController-->RefundSettlement "+orderId+" fail:获取商户信息失败,"+ JsonUtils.objectToJson(storeResult));
				//解冻商户金额
				params.put("operType",StoreVirtualOperConstants.OUT_FREEZE_MONEY);
				settleRefundService.freezeOrUnFreezeVirtualMoney(params);
				//修改订单状态为退款失败
                Map<String,Object> orderMsg = new HashMap();
                orderMsg.put("orderId",orderId);
                settleRefundService.sendOrderMessage(orderMsg,OrderUshopEnumConstants.ENUM_ORDERSTATE_REFUNDFAIL);
				return storeResult;
			}
			BigDecimal operAmount = (BigDecimal) freezeResult.getResult();
			params.put("operAmount",operAmount);
			String ysUserState = (String) storeMap.get("ysUserState");
			String ysStoreId= (String) storeMap.get("storeId");
			params.put("ysStoreId",ysStoreId);
			params.put("operateMan",storeMap.get("operateMan"));
			params.put("operateTel",storeMap.get("operateTel"));
			String ruleId = settleUshopSplitMaininfoService.getRuleIdByOrderId(orderId);
			params.put(SettleUshopRefundSearchConstants.SEARCH_REFUNDRULE,ruleId);
			//3、生成退款主信息
			Map<String,Object> createRefundMap = settleRefundService.createRefund(params);
			if(MapUtils.isEmpty(createRefundMap)){
				logger.error("SettleUshopRefundController-->RefundSettlement "+orderId+" fail:生成退款信息失败");
                //解冻退款金额
                params.put("operType",StoreVirtualOperConstants.OUT_FREEZE_MONEY);
                settleRefundService.freezeOrUnFreezeVirtualMoney(params);
				return ApiResult.failure("生成退款信息失败");
			}
			boolean createRefundFlag = (boolean) createRefundMap.get("createFlag");
			String refundId = (String) createRefundMap.get("refundId");
			params.put("refundId",refundId);
			ApiResult refundResult;
			if(createRefundFlag){
				if(StoreEnumConstants.APPROVED.equals(ysUserState)){//商户注册类型：2：为一清商户 其他为非一清
					logger.error("SettleUshopRefundController-->RefundSettlement "+orderId+" 商户为一清商户，调用分账退款");
					if(PayInfoEnumConstants.ENUM_PAYTYPE_BAL.equals(payType)){
						logger.error("SettleUshopRefundController-->RefundSettlement 余额退款");
						refundResult =  settleRefundService.balanceRefund(params);
					}else if(PayInfoEnumConstants.ENUM_PAYTYPE_CUR.equals(payType)){
						logger.error("SettleUshopRefundController-->RefundSettlement 积分退款");
						refundResult =  settleRefundService.integralRefund(params);
					}else{
						logger.error("SettleUshopRefundController-->RefundSettlement 现金退款");
						refundResult =  settleRefundService.separateRefund(params);
						boolean curNotify = orderId.substring(4,7).equals("000");
						if(ApiResultCode.SUCCESS.code().equals(refundResult.getCode()) && curNotify){
							//只有是够样优店的订单且是现金支付才通知用户中心修改积分
							Map<String,Object> sendCurrencyMsg = new HashMap();
							String customerId = (String) orderInfo.get("customerId");
							sendCurrencyMsg.put("payId",payId);
							sendCurrencyMsg.put("customerId",customerId);
							settleRefundService.sendCurrencyMessage(sendCurrencyMsg);
						}
					}
				}else{
					logger.error("SettleUshopRefundController-->RefundSettlement "+orderId+" 商户为非一清商户，攒不支持退款");
                    //解冻退款金额
                    params.put("operType",StoreVirtualOperConstants.OUT_FREEZE_MONEY);
                    settleRefundService.freezeOrUnFreezeVirtualMoney(params);
                    //修改订单状态为退款失败
                    Map<String,Object> orderMsg = new HashMap();
                    orderMsg.put("orderId",orderId);
                    settleRefundService.sendOrderMessage(orderMsg,OrderUshopEnumConstants.ENUM_ORDERSTATE_REFUNDFAIL);
					return ApiResult.failure(ApiResultCode.STOREUNSUPPORT_ERROR);
				}
				if(ApiResultCode.SUCCESS.code().equals(refundResult.getCode())){
					logger.error("SettleUshopRefundController-->RefundSettlement "+orderId+" 退款成功，生成退款流水信息");
					SettleUshopSplitRluesDO splitRluesDO = (SettleUshopSplitRluesDO) refundResult.getResult();
					params.put("splitRluesDO",splitRluesDO);
					//4、生成流水信息
					ApiResult flowResult = settleRefundService.createFlowInfo(params);
					if(!ApiResultCode.SUCCESS.code().equals(flowResult.getCode())){
						logger.error("SettleUshopRefundController-->RefundSettlement "+orderId+" 退款失败，生成退款流水信息失败");
                        //修改订单状态为退款失败
                        Map<String,Object> orderMsg = new HashMap();
                        orderMsg.put("orderId",orderId);
                        settleRefundService.sendOrderMessage(orderMsg,OrderUshopEnumConstants.ENUM_ORDERSTATE_REFUNDFAIL);
						settleRefundService.sendCheetahMessage(orderMsg);
						return ApiResult.failure();
					}
					Map<String,Object> flowMap = (Map<String, Object>) flowResult.getResult();
					BigDecimal storeAmount = (BigDecimal) flowMap.get("storeAmount");
					params.put("storeAmount",storeAmount);
				}else{
					logger.error("SettleUshopRefundController-->RefundSettlement "+orderId+" 退款失败："+JsonUtils.objectToJson(refundResult));
                    //解冻退款金额
                    params.put("operType",StoreVirtualOperConstants.OUT_FREEZE_MONEY);
                    settleRefundService.freezeOrUnFreezeVirtualMoney(params);
                    //修改订单状态为退款失败
                    Map<String,Object> orderMsg = new HashMap();
                    orderMsg.put("orderId",orderId);
                    settleRefundService.sendOrderMessage(orderMsg,OrderUshopEnumConstants.ENUM_ORDERSTATE_REFUNDFAIL);
					settleRefundService.sendCheetahMessage(orderMsg);
					return ApiResult.failure();
				}
			}else{
				logger.error("SettleUshopRefundController-->RefundSettlement "+orderId+" fail:生成退款信息报错");
                //解冻退款金额
                params.put("operType",StoreVirtualOperConstants.OUT_FREEZE_MONEY);
                settleRefundService.freezeOrUnFreezeVirtualMoney(params);
                //修改订单状态为退款失败
                Map<String,Object> orderMsg = new HashMap();
                orderMsg.put("orderId",orderId);
                settleRefundService.sendOrderMessage(orderMsg,OrderUshopEnumConstants.ENUM_ORDERSTATE_REFUNDFAIL);
				Map<String,Object> cheetahMap = new HashMap();
				cheetahMap.put("orderId",orderId);
				settleRefundService.sendCheetahMessage(cheetahMap);
				return ApiResult.failure("生成退款信息报错");
			}
			//退款成功后修改退款信息状态为退款成功
			logger.error("SettleUshopRefundController-->RefundSettlement "+orderId+" 退款成功");
			SettleUshopRefundDO settleUshopRefund = new SettleUshopRefundDO();
			settleUshopRefund.setId(refundId);
			settleUshopRefund.setStatus(SettleUshopRefundEnumConstants.ENUM_STATUS_SUC);
			settleUshopRefundService.update(settleUshopRefund);
			//通知商户中心修改商户余额
			Map<String,Object> storeMsg = settleRefundService.initChangeStoreVirtualParams(params);
			logger.error("SettleUshopRefundController-->RefundSettlement initChangeStoreVirtualParams "+orderId+" result:::"+JsonUtils.objectToJson(storeMsg));
			Map<String,Object> freezeMoneyResults = storeFeign.dealFreezeVirtulaMoney(storeMsg);
            logger.error("SettleUshopRefundController-->RefundSettlement dealFreezeVirtulaMoney "+orderId+" result:::"+JsonUtils.objectToJson(freezeMoneyResults));
			//通知订单中心修改订单状态
			Map<String,Object> orderMsg = new HashMap();
			orderMsg.put("orderId",orderId);
			settleRefundService.sendOrderMessage(orderMsg,OrderUshopEnumConstants.ENUM_ORDERSTATE_REFUNDED);
			settleRefundService.sendCheetahMessage(orderMsg);
		}catch(Exception e){
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            logger.error("SettleUshopRefundController "+orderId+" fail",e);
			return ApiResult.failure();
		}

		return ApiResult.success();
	}

	@GetMapping()
	@RequiresPermissions("settleproducer:settleUshopRefund:settleUshopRefund")
	String SettleUshopRefund(){
	    return "settleproducer/settleUshopRefund/settleUshopRefund";
	}
	
	@GetMapping("/list")
	@RequiresPermissions("settleproducer:settleUshopRefund:settleUshopRefund")
	public PageUtils list(@RequestParam Map<String, Object> params){
		//查询列表数据
        Query query = new Query(params);
		List<SettleUshopRefundDO> settleUshopRefundList = settleUshopRefundService.list(query);
		int total = settleUshopRefundService.count(query);
		PageUtils pageUtils = new PageUtils(settleUshopRefundList, total);
		return pageUtils;
	}
	
	@GetMapping("/add")
	@RequiresPermissions("settleproducer:settleUshopRefund:add")
	String add(){
	    return "settleproducer/settleUshopRefund/add";
	}

	@GetMapping("/edit/{id}")
	@RequiresPermissions("settleproducer:settleUshopRefund:edit")
	String edit(@PathVariable("id") String id,Model model){
		SettleUshopRefundDO settleUshopRefund = settleUshopRefundService.get(id);
		model.addAttribute("settleUshopRefund", settleUshopRefund);
	    return "settleproducer/settleUshopRefund/edit";
	}
	
	/**
	 * 保存
	 */
	@PostMapping("/save")
	@RequiresPermissions("settleproducer:settleUshopRefund:add")
	public R save( SettleUshopRefundDO settleUshopRefund){
		if(settleUshopRefundService.save(settleUshopRefund)>0){
			return R.ok();
		}
		return R.error();
	}
	/**
	 * 修改
	 */
	@RequestMapping("/update")
	@RequiresPermissions("settleproducer:settleUshopRefund:edit")
	public R update( SettleUshopRefundDO settleUshopRefund){
		settleUshopRefundService.update(settleUshopRefund);
		return R.ok();
	}
	
	/**
	 * 删除
	 */
	@PostMapping( "/remove")
	@RequiresPermissions("settleproducer:settleUshopRefund:remove")
	public R remove( String id){
		if(settleUshopRefundService.remove(id)>0){
		return R.ok();
		}
		return R.error();
	}
	
	/**
	 * 删除
	 */
	@PostMapping( "/batchRemove")
	@RequiresPermissions("settleproducer:settleUshopRefund:batchRemove")
	public R remove(@RequestParam("ids[]") String[] ids){
		settleUshopRefundService.batchRemove(ids);
		return R.ok();
	}
}
